package cn.yeziji.forum.dao.intf;

import cn.org.atool.fluent.mybatis.base.IBaseDao;
import cn.yeziji.forum.common.ForumPageResult;
import cn.yeziji.forum.common.key.DetailsCacheKey;
import cn.yeziji.forum.dto.details.ForumDetailDTO;
import cn.yeziji.forum.dto.details.ForumDetailPagingDTO;
import cn.yeziji.forum.dto.user.ForumUserDTO;
import cn.yeziji.forum.entity.ForumDetailsEntity;
import cn.yeziji.forum.utils.ObjectUtils;
import cn.yeziji.forum.vo.details.DetailVO;
import cn.yeziji.forum.vo.details.UserStatisticsDetailVO;

import java.util.List;

/**
 * 文章逻辑层
 *
 * @author gzkemays
 * @since 2021/12/21 15:54
 */
public interface ForumDetailsDao extends IBaseDao<ForumDetailsEntity> {

  /**
   * 删除或恢复
   *
   * <p>根据 delete 传入的值进行操作
   *
   * @param dto 文章 dto 类
   * @return 更新情况
   */
  int delOrRecovery(ForumDetailDTO dto);

  /**
   * 保存文章
   *
   * @param dto 保存对象
   * @return 数据id
   */
  int save(ForumDetailDTO dto);

  /**
   * 获取单个文章
   *
   * @param dto 入参对象 -- 主要捕获其文章 id
   * @return 文章
   */
  DetailVO getOne(ForumDetailDTO dto);

  /**
   * 获取分页列表
   *
   * @param dto 入参对象
   * @return 文章列表
   */
  ForumPageResult<DetailVO> getList(ForumDetailPagingDTO dto);

  /**
   * 获取用户的所有文章
   *
   * @param dto 分页dto
   * @return 用户文章列表
   */
  List<DetailVO> getUserDetailList(ForumDetailPagingDTO dto);

  /**
   * 获取用户点赞或收藏的文章
   *
   * @param dto 用户请求数据
   * @return 用户点赞或收藏的文章
   */
  ForumPageResult<DetailVO> getUserCollectionOrGoodDetails(ForumDetailPagingDTO dto);

  /**
   * 获取统计文章数量数据
   *
   * @param dto 用户值对象
   */
  UserStatisticsDetailVO getStatistics(ForumUserDTO dto);

  /**
   * 获取用户 7 天内发布的文章
   *
   * @param userId 用户 ID
   * @return 7 天内发布的文章
   */
  List<ForumDetailsEntity> getUser7DaysDetails(Integer userId);

  class DetailDaoCacheKey {
    int id = 0;
    int page;
    int limit;
    int userId;
    int mode;
    Boolean temp;
    String good;
    String collection;
    String delete;
    String title;
    String tags;

    public DetailDaoCacheKey paging(int page, int limit) {
      this.page = page;
      this.limit = limit;
      return this;
    }

    public DetailDaoCacheKey userId(int userId) {
      this.userId = userId;
      return this;
    }

    public DetailDaoCacheKey title(String title) {
      this.title = title == null ? "" : title;
      return this;
    }

    public DetailDaoCacheKey mode(int mode) {
      this.mode = mode;
      return this;
    }

    public DetailDaoCacheKey tags(String tags) {
      this.tags = tags == null ? "" : tags;
      return this;
    }

    public DetailDaoCacheKey temp(Boolean temp) {
      this.temp = temp;
      return this;
    }

    public DetailDaoCacheKey good(Boolean good) {
      this.good = good == null ? "null" : good ? "true" : "false";
      return this;
    }

    public DetailDaoCacheKey collection(Boolean collection) {
      this.collection = collection == null ? "null" : collection ? "true" : "false";
      return this;
    }

    public DetailDaoCacheKey delete(Boolean delete) {
      this.delete = delete == null ? "null" : delete ? "true" : "false";
      return this;
    }

    public DetailDaoCacheKey id(int id) {
      this.id = id;
      return this;
    }

    public static DetailDaoCacheKey builder() {
      return new DetailDaoCacheKey();
    }

    public static String generateKey(ForumDetailPagingDTO dto, int userId) {
      return builder()
          .paging(dto.getPage(), dto.getLimit())
          .title(dto.getTitle())
          .tags(dto.getTags())
          .mode(dto.getMode())
          .temp(dto.getTempSave())
          .userId(userId)
          .good(dto.getGood())
          .collection(dto.getCollection())
          .delete(dto.getDelete())
          .build();
    }

    public static String generateKey(ForumDetailDTO dto, int userId) {
      return builder()
          .id(dto.getId())
          .userId(userId)
          .title(dto.getTitle())
          .tags(dto.getTags())
          .buildToView(false);
    }

    public static String generateKey(ForumDetailDTO dto) {
      return builder().id(dto.getId()).title(dto.getTitle()).tags(dto.getTags()).buildToView(false);
    }

    public static String generateBlurKey(ForumDetailDTO dto) {
      return builder().id(dto.getId()).title(dto.getTitle()).tags(dto.getTags()).buildToView(true);
    }

    public String buildToView(boolean blur) {
      if (ObjectUtils.objsHasNull(this.title, this.tags)) {
        if (blur) {
          return DetailsCacheKey.CACHE_GET_DETAIL_KEY + "::" + this.id + "*";
        }
        return DetailsCacheKey.CACHE_GET_DETAIL_KEY + "::" + this.id + "::" + this.userId;
      } else {
        return DetailsCacheKey.CACHE_GET_DETAIL_KEY
            + "::"
            + this.id
            + "_"
            + this.title
            + "_"
            + this.tags;
      }
    }

    public String build() {
      return this.page
          + "_"
          + this.limit
          + "_"
          + this.title
          + "_"
          + this.tags
          + "_"
          + this.mode
          + "_"
          + this.good
          + "_"
          + this.collection
          + "_"
          + this.delete
          + "-("
          + this.userId
          + ")_"
          + this.temp;
    }
  }
}
